﻿using System;
using TaiwuModdingLib.Core.Plugin;
using HarmonyLib;
using GameData.GameDataBridge;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using HarmonyLib.Tools;
using GameData.Utilities;

namespace LogGameMessage
{
    [PluginConfig("LogGameMessage", "com.ryanli.plugins.LogGameMessage", "1")]
    public class Main : TaiwuRemakeHarmonyPlugin
    {
        public override void Initialize()
        {
            base.Initialize();
        }

        [HarmonyPatch]
        public class Patch1
        {
            [HarmonyPostfix, HarmonyPatch(typeof(Operation), "CreateMethodCall")]
            public static void Operation_CreateMethodCall_Post(ref Operation __result)
            {
                Log("MCall", __result);
            }
        }

        
        public static class Patch3
        {
            [HarmonyTranspiler]
            [HarmonyPatch(typeof(GameDataBridge), "ProcessNotifications")]
            public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions)
            {
                bool flag = false;
                foreach (var i in instructions)
                {
                    if (!flag && i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).DeclaringType.Equals(typeof(GameDataBridge.NotificationHandler)))
                    {
                        flag = true;
                        yield return new CodeInstruction(OpCodes.Ldloc_S, 28);
                        yield return CodeInstruction.Call(typeof(Patch3), "LogNoti");
                    }
                    yield return i;
                }
            }

            public static void LogNoti(List<NotificationWrapper> notifications)
            {
                try
                {
                    foreach (NotificationWrapper notificationWrapper in notifications)
                    {
                        Notification notification = notificationWrapper.Notification;
                        Log("Noti", notification);
                    }
                } catch (IndexOutOfRangeException e)
                {
                    GLog.Error(e.ToString());
                }
            }
        }


        public static void Log(string tag,Object obj)
        {
            if (obj == null)
            {
                GLog.TagLog(tag, "null");
                return;
            }
            StringBuilder builder = new StringBuilder();
            builder.Append("{");
            var fileds = obj.GetType().GetFields();
            foreach (var p in fileds)
            {
                builder.Append(p.Name + ": " + p.GetValue(obj) + ", ");
            }
            var props = obj.GetType().GetProperties();
            foreach (var p in props)
            {
                builder.Append(p.Name + ": " + p.GetValue(obj) + ", ");
            }
            builder.Append("}");
            GLog.TagLog(tag, builder.ToString());
        }
    }
}
